package server

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"golang.org/x/net/websocket"
	"live-core/core"
	"live-core/logging"
	"live-core/server/router"
	"net/http"
	"os"
)

func HTTPAPIServer() {
	logging.ZapLog.Info("Server HTTP start")

	var public *gin.Engine
	if !core.StreamManager.ServerHTTPDebug() {
		gin.SetMode(gin.ReleaseMode)
		public = gin.New()
	} else {
		gin.SetMode(gin.DebugMode)
		public = gin.Default()
	}

	public.Use(crossOrigin())
	privat := public.Group("/", gin.BasicAuth(gin.Accounts{core.StreamManager.ServerHTTPLogin(): core.StreamManager.ServerHTTPPassword()}))
	public.LoadHTMLGlob(core.StreamManager.ServerHTTPDir() + "/templates/*")

	public.GET("/", router.HTTPAPIServerIndex)
	public.GET("/pages/stream/list", router.HTTPAPIStreamList)
	public.GET("/pages/stream/add", router.HTTPAPIAddStream)
	public.GET("/pages/stream/edit/:uuid", router.HTTPAPIEditStream)
	public.GET("/pages/player/hls/:uuid/:channel", router.HTTPAPIPlayHls)
	public.GET("/pages/player/mse/:uuid/:channel", router.HTTPAPIPlayMse)
	public.GET("/pages/player/webrtc/:uuid/:channel", router.HTTPAPIPlayWebrtc)
	public.GET("/pages/multiview", router.HTTPAPIMultiview)
	public.Any("/pages/multiview/full", router.HTTPAPIFullScreenMultiView)
	public.GET("/pages/documentation", router.HTTPAPIServerDocumentation)
	public.GET("/pages/todo", router.HTTPAPIServerTodo)
	public.GET("/pages/login", router.HTTPAPIPageLogin)

	privat.GET("/streams", router.Streams)
	privat.POST("/stream/:uuid/add", router.StreamAdd)
	privat.POST("/stream/:uuid/edit", router.StreamEdit)
	privat.GET("/stream/:uuid/delete", router.StreamDelete)
	privat.GET("/stream/:uuid/reload", router.StreamReload)
	privat.GET("/stream/:uuid/info", router.StreamInfo)

	privat.POST("/streams/multi/control/add", router.StreamsMultiControlAdd)
	privat.POST("/streams/multi/control/delete", router.StreamsMultiControlDelete)

	privat.POST("/stream/:uuid/channel/:channel/add", router.StreamChannelAdd)
	privat.POST("/stream/:uuid/channel/:channel/edit", router.StreamChannelEdit)
	privat.GET("/stream/:uuid/channel/:channel/delete", router.HTTPAPIServer)
	privat.GET("/stream/:uuid/channel/:channel/codec", router.StreamChannelCodec)
	privat.GET("/stream/:uuid/channel/:channel/reload", router.StreamChannelReload)
	privat.GET("/stream/:uuid/channel/:channel/info", router.StreamChannelInfo)

	public.GET("/stream/:uuid/channel/:channel/hls/live/index.m3u8", router.StreamHLSM3U8)
	public.GET("/stream/:uuid/channel/:channel/hls/live/segment/:seq/file.ts", router.StreamHLSTS)
	public.GET("/stream/:uuid/channel/:channel/mse", func(c *gin.Context) {
		handler := websocket.Handler(router.StreamMSE)
		handler.ServeHTTP(c.Writer, c.Request)
	})
	public.POST("/stream/:uuid/channel/:channel/webrtc", router.StreamWebRTC)

	if core.StreamManager.ServerHTTPDemo() {
		public.StaticFS("/static", http.Dir(core.StreamManager.ServerHTTPDir()+"/static"))
	}
	if core.StreamManager.ServerHTTPS() {
		go func() {
			err := public.RunTLS(core.StreamManager.ServerHTTPSPort(), core.StreamManager.ServerHTTPSCert(), core.StreamManager.ServerHTTPSKey())
			if err != nil {
				logging.ZapLog.Fatal(err.Error(), zap.String("call", "ServerHTTPSPort"))
				os.Exit(1)
			}
		}()
	}

	err := public.Run(core.StreamManager.ServerHTTPPort())
	if err != nil {
		logging.ZapLog.Fatal(err.Error(), zap.String("call", "ServerHTTPPort"))
		os.Exit(1)
	}
}

//跨域处理
func crossOrigin() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}
		c.Next()
	}
}
